#include "wxMYPictureFrame.h"
#include "GraphicImageModel.h"
#include "GraphicImagePresenter.h"
#include <wx/stdpaths.h>
#include <string>
#include "MyDrawThread.h"
#include "GaussianImageFilter.h"
#include "ImageIO.h"
#include "MainFrame.h"


enum
{
	ID_SHOW_CODE,
	ID_SAVE,
	ID_TIMER = 1011u
	//ID_CAPTION

};
BEGIN_EVENT_TABLE(wxMYPictureFrame,wxFrame)
		EVT_MENU(ID_SAVE,wxMYPictureFrame::OnSave)
		EVT_PAINT(wxMYPictureFrame::OnPaint)
		EVT_TIMER(ID_TIMER,wxMYPictureFrame::OnTimer)
		EVT_ERASE_BACKGROUND(wxMYPictureFrame::OnEraseBackground)
		EVT_SIZE   (wxMYPictureFrame::OnSize)
		EVT_LEFT_DOWN(wxMYPictureFrame::OnLbuttonDown)
		EVT_RIGHT_DOWN(wxMYPictureFrame::OnRbuttonDown)
		EVT_LEFT_UP(wxMYPictureFrame::OnLbuttonUp)
		EVT_MOTION (wxMYPictureFrame::OnMouseMove)
		EVT_CLOSE(wxMYPictureFrame::OnClose)
		EVT_MENU(ID_SHOW_CODE,wxMYPictureFrame::OnShowCode)
		//EVT_MENU(ID_CAPTION,wxMYPictureFrame::OnCaption)
END_EVENT_TABLE()
void wxMYPictureFrame::imagetranceform()
{
	float width = 0;
	m_image->Get<float>("WindowWidth", width);
	if(width > 0) //it's a dicom image
	{
		unsigned char* p_rev = (unsigned char*)m_img_display->GetPixelPointer();
		short* p_img = (short*)m_image->GetPixelPointer();
		long int  size = m_image->GetSize().x()*(long int)m_image->GetSize().y();
		float _center = 0;
		m_image->Get<float>("WindowCenter", _center);
		for(long int i = 0;i<size;i++,p_img++,p_rev++)
		{
			*p_rev = (unsigned char)((*p_img-_center+0.5*width)*255/width);
		}
	}
}
wxMYPictureFrame::wxMYPictureFrame(wxWindow* parent,HPMIP::Image* image,std::string&_implement)
: wxFrame(parent, wxID_ANY, _T("Gauss_"+_implement),
		  wxDefaultPosition, wxSize(image->GetWidth()+10,image->GetHeight()+55),
		 wxDEFAULT_FRAME_STYLE),
		 m_image(image),
		  m_img_display(new HPMIP::Image(image->GetSize(),HPMIP::Image::Pixel::UChar,HPMIP::Image::Format::Grey,image->GetUnit())),
		  presenter(0L),
		  myTimer(this,ID_TIMER),
		  m_zoomer(0L)
		 
{	wxMenu * _file = new wxMenu();
	_file->Append(ID_SAVE,_T("Save Pictures"));
	int i = image->GetWidth();
	int j = m_img_display->GetWidth();
	wxMenuBar * bar = new wxMenuBar();
	wxMenu *show_code = new wxMenu();
	show_code->Append(ID_SHOW_CODE,_T("Show Code"));
	bar->Append(_file,_T("File"));
	bar->Append(show_code,_T("Show code"));
	SetMenuBar(bar);
	assert(image!= 0L);
	imagetranceform();
	presenter =  new GraphicImagePresenter(m_hWnd, image->GetWidth(),image->GetHeight(),"OPEN_GL");
	GraphicImageModel * model = new GraphicImageModel();
	float width = 0;
	m_image->Get<float>("WindowWidth", width);
	if(width>0)
	model->GetImageGraph()->SetImage(m_img_display);
	else
		model->GetImageGraph()->SetImage(m_image);
	presenter->SetModel(model);
	if(presenter)
		m_zoomer = new HPMIP::GraphicImageZoomController(presenter);
	workThread = (MyThread*)0L;
	//myTimer = new wxTimer(this,ID_TIMER);
	//myTimer->SetOwner(this);
	//myTimer 
//	myTimer.Start(1000);
	//workThread = new MyThread(this,_implement);
	//if(workThread->Create()== wxTHREAD_NO_ERROR)
		//workThread->Run();
	SetTitle(_T("being processed......."));
	ImageProcessing::GaussianImageFilter *GaussProcess= new ImageProcessing::GaussianImageFilter(4, "Linear_CUDA");

	//wxMutexGuiEnter();
	//HPMIP::Image * tmp = ((wxMYPictureFrame*)myMainFrame)->GetImage();
	//wxMutexGuiLeave();
	GaussProcess->Run(m_image,7);
	Refresh();
	
}
void wxMYPictureFrame::OnTimer(wxTimerEvent& event)
{

	workThread->Pause();
	imagetranceform();
	OutputDebugStringA("work pause\n");
	////wuspendThread(workThread->get)
	MyDrawThread * draw = new MyDrawThread(this);
	if(draw->Create() == wxTHREAD_NO_ERROR)
		draw->Run();
	OutputDebugStringA("work resume\n");
	workThread->Resume();
	//workThread->Run();
}
void wxMYPictureFrame::OnClose(wxCloseEvent& event)
{
	myTimer.Stop();
	if(workThread->IsAlive())
		workThread->Kill();
	
	if(presenter)
		delete presenter;
	if(m_zoomer)
		delete m_zoomer;
	//if(workThread)
		//delete workThread;
	if(m_image)
		delete m_image;
	wxFrame::OnCloseWindow(event);
}
void wxMYPictureFrame::OnSave(wxCommandEvent& event)
{
	wxString savefilename = wxFileSelector( wxT("Save Image"),
		wxEmptyString,
		wxEmptyString,
		(const wxChar *)NULL,
		wxT("BMP files (*.bmp)|*.bmp|")
		//wxT("PNG files (*.png)|*.png|")
		wxT("JPEG files (*.jpg)|*.jpg|")
		wxT("DICM files (*.dcm)|*.dcm|")
		wxT("TIFF files (*.tif)|*.tif"),
		//wxT("PCX files (*.pcx)|*.pcx|")
		//wxT("ICO files (*.ico)|*.ico|")
		//wxT("CUR files (*.cur)|*.cur"),
		wxFD_SAVE,
		this);

	if ( savefilename.empty() )
		return;
	//wxString extent;
	//wxFileName::SplitPath(savefilename, NULL, NULL, &extent);
	wxString extent = savefilename.substr(savefilename.find_last_of('.'),savefilename.size());
	HpmipIO::ImageIO *carrier = 0L;
	if(extent == _(".dcm"))
		carrier = new HpmipIO::ImageIO("dicom_gdcm");
	else if(extent == _(".jpg")||extent == ".JPG")
		carrier = new HpmipIO::ImageIO("jpeg_ijg");
	else if(extent == _(".tif"))
		carrier = new HpmipIO::ImageIO("tiff_libtiff");
	else if(extent == _(".bmp"))
		carrier = new HpmipIO::ImageIO("bmp_GDI");
	if(carrier)
	{
		carrier->SetImageName(savefilename.c_str());
		carrier->SetImage(m_image);
		carrier->Write();
	}
}
void wxMYPictureFrame::OnPaint(wxPaintEvent& event)
{
	wxPaintDC dc( this );
	PrepareDC( dc );
	imagetranceform();

	if(presenter != 0L)
	{
		presenter->Update();
		//presenter->GetModel()->GetImageGraph()->SetImage(m_image);
	}
}
void wxMYPictureFrame::OnEraseBackground(wxEraseEvent& rEvent)
{
	//wxFrame::OnEraseBackground(rEvent);
	//this->Refresh(false);
	//RedrawWindow();
	
}
wxMYPictureFrame::~wxMYPictureFrame(void)
{
}
void wxMYPictureFrame::OnRbuttonDown(wxMouseEvent &event)
{
	;
}
void wxMYPictureFrame::OnLbuttonDown(wxMouseEvent &event)
{
	if(m_zoomer)
	{ 
		int x,y;
		event.GetPosition(&x,&y);
		int pos[2] = {x,y};
		m_zoomer->OnMouseDown(pos);
	}  

}
void wxMYPictureFrame::OnLbuttonUp(wxMouseEvent &event)
{
	if(m_zoomer)
	{ 
		int x,y;
		event.GetPosition(&x,&y);
		int pos[2] = {x,y};
		m_zoomer->OnMouseUp(pos);
	}  

}
void wxMYPictureFrame::OnMouseMove(wxMouseEvent &event)
{
	if(m_zoomer)
	{ 
		int x,y;
		event.GetPosition(&x,&y);
		int pos[2] = {x,y};
		m_zoomer->OnMouseMove(pos);
	}  
}
void wxMYPictureFrame::OnSize(wxSizeEvent& sizeevent)
{
	wxWindow::SetSize(sizeevent.GetSize());
	if(presenter)
		presenter->GetRenderer()->GetContext()->OnSizeChanged(sizeevent.GetSize().GetWidth(),sizeevent.GetSize().GetWidth());
}

void wxMYPictureFrame::OnShowCode(wxCommandEvent& event)
{
	SourceFrame *frame = new SourceFrame(_("Second.htm"), wxDefaultPosition, wxSize(640, 480));

	frame->Show();
}